package com.surfacing.rcp.client.modelManager;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.widgets.Display;

import com.surfacing.rcp.client.providers.JournalViewFilter;
import com.surfacing.rcp.model.common.IProgramStatus;
import com.surfacing.rcp.model.common.ITransportStatus;
import com.surfacing.rcp.model.entity.Journal;

/**
 * All transports
 * 
 * @author b.thek
 */
public class JournalManager extends PropertyManager implements
		ITransportStatus, IProgramStatus {
	// the item list
	private List<Journal> objectList = new ArrayList<Journal>();
	// the date of the transports displayed in the transports view
	private Calendar displayedDate;

	/**
	 * Default class constructor
	 */
	public JournalManager() {
	}

	/**
	 * Adds a new journal to the list
	 * 
	 * @param journal
	 *            the journal to add
	 */
	public void add(final Journal journal) {
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				// add the item if we do not have it
				if (!objectList.contains(journal)) {
					objectList.add(journal);
					firePropertyChange("JOURNAL_ADD", null, journal);
				}
			}
		});
	}

	/**
	 * Removes the journal from the list
	 * 
	 * @param journal
	 *            the journal to remove
	 */
	public void remove(final Journal journal) {
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				objectList.remove(journal);
				firePropertyChange("JOURNAL_REMOVE", journal, null);
			}
		});
	}

	/**
	 * Updates the journal at the list
	 * 
	 * @param journal
	 *            the journal to update
	 */
	public void update(final Journal journal) {
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				// assert we have this journal
				if (!objectList.contains(journal))
					return;
				// get the position of the entry
				int id = objectList.indexOf(journal);
				objectList.set(id, journal);
				firePropertyChange("JOURNAL_UPDATE", null, journal);
			}
		});
	}

	/**
	 * Removes all elements from the list EXCEPT the transports from the current
	 * day.
	 */
	public void removeAllEntries() {
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				// keep all transports form the current day
				Iterator<Journal> iter = objectList.iterator();
				while (iter.hasNext()) {
					Journal journal = iter.next();
					// check the date
					iter.remove();
				}
				firePropertyChange("JOURNAL_CLEARED", null, null);
			}
		});
	}

	/**
	 * Returns a list of all transports in the system.
	 * 
	 * @return all managed transports
	 */
	public List<Journal> getJournalList() {
		return objectList;
	}

	/**
	 * Converts the list to an array
	 * 
	 * @return the list as a array
	 */
	public Object[] toArray() {
		return objectList.toArray();
	}

	/**
	 * Informs the views that the selected date in the journal view filter has
	 * changed.
	 * 
	 * @param newDate
	 *            the newDate to display
	 */
	public void fireJournalViewFilterChanged(final Calendar newDate) {
		this.displayedDate = newDate;
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				// fire a property change event to notify the viewers that the
				// date changed
				firePropertyChange("JOURNAL_DATE_CHANGED", null, newDate);
			}
		});
	}

	/**
	 * Informs the views that the filter for the journal has changed
	 */
	public void fireJournalFilterChanged(final JournalViewFilter newFilter) {
		// notify the listeners
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				firePropertyChange("JOURNAL_FILTER_CHANGED", null, newFilter);
			}
		});
	}

	/**
	 * Returns the date of the currently displayed transports choosen by the
	 * filter view.
	 * 
	 * @return displayDate the displayed date
	 */
	public Calendar getDisplayedDate() {
		return displayedDate;
	}

	/**
	 * Returns a list of all transports that are assigned to this vehicle.
	 * 
	 * @param vehicleName
	 *            the name of the vehicle to list the transports
	 * @return journal list filtered by vehicle
	 */
	// public List<Journal> getJournalsByVehicle(String vehicleName) {
	// // the result list
	// List<Journal> filteredList = new ArrayList<Journal>();
	// // loop
	// for (Journal journal : objectList) {
	// // get the vehicle
	// VehicleDetail assignedVehicle = journal.getVehicleDetail();
	// // assert valid
	// if (assignedVehicle == null)
	// continue;
	// if (journal.getProgramStatus() != IProgramStatus.PROGRAM_STATUS_UNDERWAY)
	// continue;
	// // check the vehicle
	// if (assignedVehicle.getVehicleName().equals(vehicleName))
	// filteredList.add(journal);
	// }
	// return filteredList;
	// }

	/**
	 * Returns a list of the transports with the program status 'journal' which
	 * are assigned to this vehicle and have no set journal status S6 yet.
	 * 
	 * @param vehicleName
	 *            the name of the vehicle to list the transports
	 * @return transort list filtered by vehicle, program status 'journal' and
	 *         without journal status S6
	 */
	// public List<Journal> getJournalJournalsByVehicleAndStatusSix(
	// String vehicleName) {
	// // the result list
	// List<Journal> filteredList = new ArrayList<Journal>();
	// // loop
	// for (Journal journal : objectList) {
	// // get the vehicle
	// VehicleDetail vehicle = journal.getVehicleDetail();
	// int programStatus = journal.getProgramStatus();
	// // assert valid
	// if (vehicle == null)
	// continue;
	// // check the vehicle
	// if (vehicle.getVehicleName().equalsIgnoreCase(vehicleName)
	// && programStatus == PROGRAM_STATUS_JOURNAL)
	// filteredList.add(journal);
	// }
	// return filteredList;
	// }
}